package com.zlcx.tz.live.common.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>redis客户端配置</p>
 * <PRE>
 * <BR>    修改记录
 * <BR>-----------------------------------------------
 * <BR>    修改日期         修改人          修改内容
 * </PRE>
 *
 * @author zl
 * @version 1.0
 * @date Created in 2017/11/30 15:32
 * @copyright: Copyright (c) founders
 */
@Configuration
public class RedisConfig {
    /**
     * 注解里的字符串值必须使用字面量或者常量,所以单独定义常量, 同时用在注解和Cache定义中
     */
    public static class CacheKeys {
        private CacheKeys() {
        }

        public static final String ROOM_USER_LIST = "tz-live-video:room:user-list";

        public static final String ROOM_SWITCHED = "tz-live-video:switched";

        public static final String ROOM_FREE = "tz-live-video:free";

        public static final String USER_TOTAL_LIVE_TIME = "tz-live-video:user:total:live-time";

        public static final String ROOM_FREE_NUM = "tz-live-video:free:num";

        public static final String TIME_LEARN_ROOM_TOTAL_NUM = "tz-live-video:time-learn-room:total-num";



    }

    /**
     * 这里记录cache key和过期时间
     */
    private enum CacheEnum {
        /**
         *
         */
        USER_TOTAL_LIVE_TIME(CacheKeys.USER_TOTAL_LIVE_TIME, 60 * 60),
        TIME_LEARN_ROOM_TOTAL_NUM(CacheKeys.TIME_LEARN_ROOM_TOTAL_NUM, 60 * 10),
        ;

        public final String cacheName;
        public final int expireInSeconds;

        CacheEnum(String cacheName, int expireInSeconds) {
            this.cacheName = cacheName;
            this.expireInSeconds = expireInSeconds;
        }
    }

    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setUsePrefix(true);
        //缓存默认60秒, 如果特别情况在CacheEnum里设置
        cacheManager.setDefaultExpiration(60);

        Map<String, Long> expires = Arrays.stream(RedisConfig.CacheEnum.values())
                .collect(Collectors.toMap(e -> e.cacheName, e -> Long.valueOf(e.expireInSeconds)));

        cacheManager.setExpires(expires);
        return cacheManager;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        om.setSerializationInclusion(Include.NON_NULL);
        om.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jackson2JsonRedisSerializer);

        return template;
    }

//    @Bean
//    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory factory){
//        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
//        container.setConnectionFactory(factory);
//        container.addMessageListener(recordVideoListener(), recordVideoTopic());
//        container.addMessageListener(recordVideoFinishListener(), recordVideoFinishTopic());
//        return container;
//    }

    /**
     * 实例化 SetOperations 对象,可以使用 Set 操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForSet();
    }
    /**
     * 实例化 HashOperations 对象,可以使用 Hash 类型操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForHash();
    }

    /**
     * 开始合成视频
     * @return
     */
//    @Bean
//    public ChannelTopic recordVideoTopic() {
//        return new ChannelTopic("/record/recordvideo");
//    }

    /**
     * 视频合成结束
     * @return
     */
//    @Bean
//    public ChannelTopic recordVideoFinishTopic() {
//        return new ChannelTopic("/record/recordvideofinish");
//    }

//    @Bean
//    public SubscribeRecordVideoListener recordVideoListener() {
//        return new SubscribeRecordVideoListener();
//    }
//
//    @Bean
//    public SubscribeRecordVideoFinishListener recordVideoFinishListener() {
//        return new SubscribeRecordVideoFinishListener();
//    }






}
